package com.zysc.processflow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zysc.processflow.common.util.StringUtils;
import com.zysc.processflow.entity.Organization;
import com.zysc.processflow.entity.Person;
import com.zysc.processflow.mapper.OrganizationMapper;
import com.zysc.processflow.service.IOrganizationService;
import com.zysc.processflow.common.base.BaseService;
import com.zysc.processflow.service.IPersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织机构表 服务实现类
 * </p>
 *
 * @author 正元智慧城市_
 * @since 2022-11-18
 */
@Service
public class OrganizationServiceImpl extends BaseService<OrganizationMapper, Organization> implements IOrganizationService {

    @Autowired
    IPersonService personService;

    @Override
    public List<Organization> GetOrganizationListByPage(IPage<Organization> page, String name, String qyflag, String district, String type, String fathername) {
        if(!StringUtils.isNull(district)&&district.startsWith("sys_")){
            district = district.replace("sys_","");
        }

        LambdaQueryWrapper<Organization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(!StringUtils.isNull(name), Organization::getName, name)
                .eq(!StringUtils.isNull(qyflag) && qyflag.equals("1"),Organization::getType,"1")
                .eq(!StringUtils.isNull(district),Organization::getDistrictcode,district)
                .eq(!StringUtils.isNull(type),Organization::getType,type)
                .like(!StringUtils.isNull(fathername),Organization::getFathername,fathername)
                .last("ORDER BY CASE type WHEN '1' THEN 1 WHEN '3' THEN 2 WHEN '11' THEN 3 END ASC,id asc");
        List<Organization> list = new ArrayList<>();
        if (page != null) {
            list = this.baseMapper.selectPage(page, queryWrapper).getRecords();
        }else{
            list = this.baseMapper.selectList(queryWrapper);
        }
        return list;
    }


    @Override
    public List<Person> GetAllUserinfoByOrgid(String id) {
        List<Person> personListByOrgId = personService.getPersonListByOrgId(id);
        return personListByOrgId;
    }

    @Override
    public List<String> getOwnerArray(String orgid,String currentorgid) {
        List<String> result =new ArrayList<>();
        String temp = orgid;
        while(true){
            Organization organization = this.getById(temp);
            if(organization==null){
                break;
            }else{
                result.add(temp);
                temp = organization.getFatherid();
                if((!StringUtils.isNull(currentorgid) && organization.getId().equals(currentorgid) )){
                    break;
                }
            }
        }
        Collections.reverse(result);
        return result;
    }

    @Override
    public Boolean saveOrUpdateOrgnInfo(Organization entity) {
        Boolean b1 = true;//保存原信息
        Boolean b2 = true;//保存path字段
        String fatherid = entity.getFatherid();
        if(!StringUtils.isNull(fatherid) &&StringUtils.isNull(entity.getFathername())){
            Organization organization = this.getById(fatherid);
            if(organization!=null){
                entity.setFathername(organization.getName());
            }
        }
        Long tm = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        if(StringUtils.isNull(entity.getId())){
            entity.setCreatetime(tm);
        }else{
            entity.setUpdatetime(tm);
        }
        b1 = this.saveOrUpdate(entity);
        //加上path字段（从根到此节点的id路径，用#分隔）
        List<String> pathList = getOwnerArray(entity.getId(),null);
        String path = String.join("#",pathList);
        entity.setPath(path);
        //将企业部门的code填充企业的code
        if(StringUtils.isNull(entity.getCode()) && StringUtils.equalsAndNotNull(entity.getType(),"11")){
            Organization enterprise = getEnterpriseCodeByDepartId(entity);
            if(enterprise!=null) {
                entity.setCode(enterprise.getCode());
                entity.setIsdel(enterprise.getIsdel());//部门的isdel随企业的isdel
            }
        }
        b2 = this.saveOrUpdate(entity);
        return b1 && b2;
    }


    //传入小部门,获得企业的信息(从全部数据库里查,非isdel=0的)
    public Organization getEnterpriseCodeByDepartId(Organization dept){
        if (StringUtils.equalsAndNotNull(dept.getType(),"11")) {
            Organization fatherOrg = dept;
            while (StringUtils.equalsAndNotNull(fatherOrg.getType(), "11") && fatherOrg != null) {//有部门嵌套部门的情况,所以要循环
                fatherOrg = this.baseMapper.getOrganizationByIdFromAll(fatherOrg.getFatherid());
            }
            if (fatherOrg != null && StringUtils.equalsAndNotNull(fatherOrg.getType(), "1")) {
                return fatherOrg;
            }
        }
        return null;
    }
    @Override
    //数据权限：根据一个orgid获取该显示的数据
    public List<Organization> getAllOrgFlowedByorgId(String currentorgid,String currentorgtype) {
        return personService.getAllOrgFlowedByorgId(currentorgid,currentorgtype);
    }
    @Override
    public Boolean updateFatherNameAndPath() {
        List<Organization> list = this.list();
        list.stream().forEach(item->{
            //1.修改父机构名称
            String fatherid = item.getFatherid();
            if(!StringUtils.isNull(fatherid)){
                Organization organization = this.getById(fatherid);
                if(organization!=null){
                    item.setFathername(organization.getName());
                }
            }
            //2.修改path
            List<String> pathList = getOwnerArray(item.getId(),null);
            String path = String.join("#",pathList);
            item.setPath(path);

            //3.小部门修改code为企业的code
            //将企业部门的code填充企业的code
            if(StringUtils.isNull(item.getCode()) && StringUtils.equalsAndNotNull(item.getType(),"11")){
                Organization enterprise = getEnterpriseCodeByDepartId(item);
                if(enterprise!=null) {
                    item.setCode(enterprise.getCode());
                    item.setIsdel(enterprise.getIsdel());//部门的isdel随企业的isdel
                }
            }
            this.saveOrUpdate(item);
        });
        return true;
    }

    @Override
    public Organization getOrgByTyshxydm(String tyshxydm) {
        if(StringUtils.isNull(tyshxydm)){
            return null;
        }
        LambdaQueryWrapper<Organization> qw = new LambdaQueryWrapper<>();
        qw.eq(Organization::getCode,tyshxydm)
        .eq(Organization::getType,"1");
        List<Organization> orgs = this.list(qw);
        if(orgs.size()>0){
            return orgs.get(0);
        }
        return null;
    }

    @Override
    public List<Organization> getChildrenOrg(String orgid) {
        List<Organization> result = new ArrayList<>();
        Organization org = this.getOrgByOrgIdOrTyshxydm(orgid);
        if(org==null){
            return result;
        }
        LambdaQueryWrapper<Organization> qw = new LambdaQueryWrapper<>();
        qw.eq(Organization::getCode,org.getCode());
        result = this.list(qw);
        return result;
    }

    @Override
    public Organization getOrgByOrgIdOrTyshxydm(String orgid) {
        Organization org = this.getById(orgid);
        if(org==null){
            org = this.getOrgByTyshxydm(orgid);
        }
        if(org==null){
            org = this.getById("sys_"+orgid);
        }
        return org;
    }

    @Override
    public List<Map> GetSonNodeById(String orgid) {
        LambdaQueryWrapper<Organization> qw  = new LambdaQueryWrapper<>();
        qw.eq(Organization::getFatherid,orgid);
        List<Organization> list = this.list(qw);
        List<Map> collect = list.stream().map(item -> {
            Map map = new HashMap<>();
            map.put("id",item.getId());
            map.put("value",item.getId());
            map.put("code",item.getCode());
            map.put("name",item.getName());
            map.put("label",item.getName());
            map.put("type",item.getType());
            qw.clear();
            qw.eq(Organization::getFatherid,item.getId());
            List<Organization> listtemp = this.list(qw);
            if(listtemp.size()>0){
                map.put("hasChildren",true);
            }else{
                map.put("leaf",true);
            }
            map.put("childrenCount",listtemp.size());
            return map;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<Organization> getOrgDataListByKeyword(IPage<Organization> page, List<String> queryColomnList, String keyword, Boolean precise) {
        List<Organization> list = new ArrayList<>();
        if(precise){
            list = this.baseMapper.getOrgDataListByKeywordPrecise(page,queryColomnList,keyword);
        }else{
            list = this.baseMapper.getOrgDataListByKeyword(page,queryColomnList,keyword);
        }
        return list;
    }

    @Override
    public List<Organization> getTestData() {
        return this.baseMapper.getTestOrganization();
    }
    @Override
    public Organization getOrganizationFromAll(String tyshxydm) {
        return this.baseMapper.getOrganizationFromAll(tyshxydm);
    }
    @Override
    public Organization setIsDelByTyshxydm(String enterprisecode) {
        //逻辑删除的企业当作备份企业,如果有用到会被'转正',并且是包含全部部门的转正
        Organization qy = null;
        try{
            //这里查询的是全部的,而不是isdel是0的
            qy = this.baseMapper.getOrganizationFromAll(enterprisecode);
            if(qy!=null){
                String code = qy.getCode();
                List<Organization> children = this.baseMapper.getOrgChildrenFromAll(code);
                children.add(qy);
                children.forEach(item->{
                    if(!StringUtils.isNull(item.getId())){
                        this.baseMapper.setIsDelByOrgId(item.getId(),0);
                    }
                });
            }
        }catch (Exception e){

        }
        return qy;
    }

    public List<Organization> getChildrenByOrg(String orgid,List<Organization> result,List<Organization> allOrgList){

        List<Organization> children = allOrgList.stream().filter(item->!StringUtils.isNull(item.getFatherid()) && item.getFatherid().equals(orgid)).collect(Collectors.toList());

        children.stream().forEach(child->{
            result.add(child);
            List<Organization> temp =getChildrenByOrg(child.getId(),result,allOrgList);
        });
        return result;
    }
}
